﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ReadeAssetManager
{
    public partial class ucSearchAsset : UserControl, ISearchControl
    {
        AMSServiceRef.User _user;

        private const string DATE_IS = "Date Is";
        private const string DATE_BEG = "Date Beginning";
        private const string DATE_END = "Date Ending";
        private const string DATE_BET = "Date Between";
        private const string DATE_ANY = "Any Date";

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="CurrentUser">[AMSServiceRef.User] The current application user.</param>
        public ucSearchAsset(AMSServiceRef.User CurrentUser)
        {
            InitializeComponent();
            _user = CurrentUser;
            LoadDateSearchOptions();
        }

        /// <summary>
        /// BuildAssetList
        /// Creates and returns a List of AMSServiceRef.Asset objects matching the search
        /// criteria.  This method is called indirectly from frmMain via a delegate in the
        /// ucSearch control.
        /// </summary>
        /// <returns>[List<AMSServiceRef.Asset>] List of assets matching the search criteria.</returns>
        public List<AMSServiceRef.Asset> BuildAssetList()
        {
            List<AMSServiceRef.Asset> assets = new List<AMSServiceRef.Asset>();

            if (_user != null)
            {
                foreach(AMSServiceRef.Asset asset in _user.Assets)
                {
                    if (IsAssetMatch(asset))
                        assets.Add(asset);
                }
            }

            return assets;
        }

        /// <summary>
        /// IsAssetMatch
        /// Determines whether the given asset matches the search parameters.
        /// </summary>
        /// <param name="CurrentAsset">[AMSServiceRef.Asset] The asset being checked.</param>
        /// <returns>[bool] True if this asset fits the search parameters, otherwise false.</returns>
        private bool IsAssetMatch(AMSServiceRef.Asset CurrentAsset)
        {
            // No search options were selected
            if ((txtComments.Text.Length + txtMake.Text.Length + txtManuf.Text.Length + txtMeta.Text.Length +
                txtModel.Text.Length + txtName.Text.Length + txtSerial.Text.Length == 0) && !dtpFrom.Enabled &&
                !dtpTo.Enabled)
            {
                return true;
            }

            // Comments
            if (txtComments.Text.Length > 0 && !CurrentAsset.Comments.Contains(txtComments.Text))
                return false;

            // Make
            if (txtMake.Text.Length > 0 && !CurrentAsset.Make.Contains(txtMake.Text))
                return false;
            // Manufacturer
            if (txtManuf.Text.Length > 0 && !CurrentAsset.Manufacturer.Contains(txtManuf.Text))
                return false;

            // Metadata
            if (txtMeta.Text.Length > 0 && !CurrentAsset.Metadata.Contains(txtMeta.Text))
                return false;

            // Model
            if (txtModel.Text.Length > 0 && !CurrentAsset.Model.Contains(txtModel.Text))
                return false;

            // Name
            if (txtName.Text.Length > 0 && !CurrentAsset.Name.Contains(txtName.Text))
                return false;

            // Serial number
            if (txtSerial.Text.Length > 0 && !CurrentAsset.SerialNumber.Contains(txtSerial.Text))
                return false;

            // Date From/To
            if (dtpFrom.Enabled && dtpTo.Enabled)
                return IsValidDate(dtpFrom, cmbYear, CurrentAsset.Year, true) &&
                       IsValidDate(dtpTo, cmbYear, CurrentAsset.Year, false);

            else if (dtpFrom.Enabled)
                return IsValidDate(dtpFrom, cmbYear, CurrentAsset.Year, true);

            else if (dtpTo.Enabled)
                return IsValidDate(dtpTo, cmbYear, CurrentAsset.Year, false);

            return true;
        }

        /// <summary>
        /// LoadDateSearchOptions
        /// Fills the cmbYear control with the default values.
        /// </summary>
        private void LoadDateSearchOptions()
        {
            cmbYear.Items.Clear();
            cmbYear.Items.Add(DATE_IS);
            cmbYear.Items.Add(DATE_BEG);
            cmbYear.Items.Add(DATE_END);
            cmbYear.Items.Add(DATE_BET);
            cmbYear.Items.Add(DATE_ANY);
            cmbYear.Text = DATE_ANY;
        }

        /// <summary>
        /// cmbYear_TextChanged
        /// Enables/disables the appropriate date fields as the date search options are changed.
        /// </summary>
        /// <param name="sender">[object] The cmbYear control.</param>
        /// <param name="e">[EventArgs] The standard event arguments for a TextChanged event.</param>
        private void cmbYear_TextChanged(object sender, EventArgs e)
        {
            switch(cmbYear.Text)
            {
                case DATE_IS:
                    dtpFrom.Enabled = true;
                    dtpTo.Enabled = false;
                    break;
                case DATE_BEG:
                    dtpFrom.Enabled = true;
                    dtpTo.Enabled = false;
                    break;
                case DATE_END:
                    dtpFrom.Enabled = false;
                    dtpTo.Enabled = true;
                    break;
                case DATE_BET:
                    dtpFrom.Enabled = true;
                    dtpTo.Enabled = true;
                    break;
                case DATE_ANY:
                    dtpFrom.Enabled = false;
                    dtpTo.Enabled = false;
                    break;
                default:
                    dtpFrom.Enabled = false;
                    dtpTo.Enabled = false;
                    break;
            }
        }

        /// <summary>
        /// IsValidDate
        /// Determines whether the date given in DateToValidate meets the criteria given
        /// by the value in the Picker control and the selected option in the DateOption
        /// control.
        /// </summary>
        /// <param name="Picker">[DateTimePicker] The control containing the criteria value.</param>
        /// <param name="DateOption">[ComboBox] The control indicating how and whether the date should be read.</param>
        /// <param name="DateToValidate">[DateTime] The AMSServiceRef.Asset date being checked.</param>
        /// <param name="FromDate">[bool] True if checking the from date field, otherwise false.  Required for Date Between.</param>
        /// <returns>[bool] True if the DateToValidate meets the criteria, otherwise false.</returns>
        private bool IsValidDate(DateTimePicker Picker, ComboBox DateOption, DateTime DateToValidate, bool FromDate)
        {
            switch (DateOption.Text)
            {
                case DATE_IS:
                    if (FromDate)
                        return (DateToValidate == Picker.Value);
                    break;
                case DATE_BEG:
                    if (FromDate)
                        return (DateToValidate >= Picker.Value);
                    break;
                case DATE_END:
                    if (!FromDate)
                        return (DateToValidate <= Picker.Value);
                    break;
                case DATE_BET:
                    if (FromDate)
                        return (DateToValidate >= Picker.Value);
                    else
                        return (DateToValidate <= Picker.Value);
                    break;
                case DATE_ANY:
                    return true;
                    break;
                default:
                    // An unexpected option was selected.
                    return false;
                    break;
            }
            return false;
        }
    }
}
